home *** CD-ROM | disk | FTP | other *** search
- /* ReadPICT.c */
- /*
- * Picture I/O -- more or less from TechNote 154.
- *
- * For some reason, the PICT dimensions do not correctly
- * describe the picture: it loses its 300 dpi resolution
- * when read in. MAGIC scales the PICT by a factor of 4.
- * We should get the "real" scale factor by inserting
- * our function into the StdBits bottleneck.
- */
- #include "CleanPICT.h"
- #include <SysErr.h>
-
- /*
- * See TechNote 27 (original format), and the Essential
- * MacTutor, vol 3, p 417. (This struct is now unused
- * but, since it typed it in, it might as well stay.)
- */
- typedef struct {
- OSType fType; /* 'DRWG' for MacPaint files */
- short hdrID; /* 'MD' for MacPaint format */
- short version; /* File version */
- short prRec[60]; /* 120 byte print record */
- Fixed xOrigin; /* Drawing origin */
- Fixed yOrigin; /* Drawing origin */
- Fixed xScale; /* Screen resolution */
- Fixed yScale; /* Screen resolution */
- short atrState[31]; /* Drawing attribute state */
- short lCnt; /* Top-level objects */
- short lTot; /* Total number of objects */
- long lSiz; /* Total size of list */
- Fixed top; /* Box enclosing all objects */
- Fixed left;
- Fixed bottom;
- Fixed right;
- short filler1[141]; /* 282 bytes unused */
- } MacDrawHdrRec;
-
- static int PICTfile; /* The file ioRefNum */
-
- /*
- * Use this to peek into the bitmap as it is read in.
- * The peeking is done by jumping into the Debugger.
- */
- pascal void myStdBits(
- BitMap *, Rect *, Rect *, int, RgnHandle);
- pascal void read_picture_data(Ptr, int);
- pascal void write_picture_data(Ptr, int);
-
- /*
- * read_picture() reads the picture from the PICT file,
- * constructing the window at the proper size.
- */
- OSErr
- read_picture(window, theFile)
- WindowPtr window;
- int theFile;
- {
- PicHandle handle;
- QDProcs procedures;
- OSErr status;
- long size;
- long place;
- Rect box;
- GrafPtr oldPort;
- MacDrawHdrRec header;
-
- PICTfile = theFile;
- handle = (PicHandle) NewHandle(sizeof (Picture));
- if (handle == NIL) {
- DebugStr("\pCan't get memory for picture");
- return (MemError());
- }
- /*
- * Read the MacDraw header record -- that was a
- * good idea, but it didn't work as the headers
- * are garbage.
- */
- if (sizeof header != 512)
- DebugStr("\pMacDrawHdrRec wrong size!");
- read_picture_data((Ptr) &header, sizeof header);
- HLock(handle);
- read_picture_data((Ptr) *handle, sizeof (Picture));
- HUnlock(handle);
- box = (**handle).picFrame;
- DOC.pictSize = box;
- box.right *= MAGIC;
- box.bottom *= MAGIC;
- GetPort(&oldPort);
- DOC.pictPort = CreateOSGrafPort(box);
- if (DOC.pictPort == NIL) {
- DebugStr("\pNo memory for picture");
- SetPort(oldPort);
- return (MemError());
- }
- SetStdProcs(&procedures);
- DOC.pictPort->grafProcs = &procedures;
- procedures.getPicProc = (Ptr) read_picture_data;
- /* procedures.bitsProc = (Ptr) myStdBits; -- unused */
- DrawPicture(handle, &box);
- DOC.pictPort->grafProcs = NIL;
- DisposHandle((Handle) handle);
- /*
- * Erase a 1-pixel frame around the picture so
- * the island searcher never has to worry about
- * falling off the end of the universe.
- */
- PenPat(white);
- FrameRect(&DOC.pictSize);
- PenNormal();
- SetPort(oldPort);
- /*
- * Check for errors by getting the file position and
- * checking that it is at the end of file.
- */
- if ((status = GetEOF(PICTfile, &size)) != noErr
- || (status = GetFPos(PICTfile, &place)) != noErr) {
- DebugStr("\pCan't get EOF or file position");
- return (status);
- }
- if (size != place) {
- DebugStr("\pDidn't read entire picture");
- return (dsSysErr);
- }
- /*
- * Ok so far. Now, change the window size so the
- * picture fills the window -- but keep the proportions
- * as close to the original as possible.
- */
- SetRect(
- &box,
- 2,
- GetMBarHeight() * 2,
- width(DOC.pictSize) + 2,
- GetMBarHeight() * 2 + height(DOC.pictSize)
- );
- if (box.bottom > (screenBits.bounds.bottom - 2)) {
- box.bottom = screenBits.bounds.bottom - 2;
- size = height(box);
- box.right = box.left
- + ((long) width(box) * size) / height(DOC.pictSize);
- }
- if (box.right > (screenBits.bounds.right - 2)) {
- box.right = screenBits.bounds.right - 2;
- size = width(box);
- box.bottom = box.top
- + ((long) height(box) * size) / width(DOC.pictSize);
- }
- SizeWindow(window, width(box), height(box), TRUE);
- InvalRect(&window->portRect);
- ShowWindow(window);
- return (MemError());
- }
-
- /*
- * This should implement a "vanilla" StdBits -- for some
- * reason, though, it "bombs" when it runs to completion:
- * perhaps because it's called with a NULL argument at
- * eof. It was only used to check that the created
- * "MAGIC" bitmap is the same size as the bitmap inside
- * of the PICT -- by running the function under the
- * debugger.
- */
- pascal void
- myStdBits(srcBits, srcRect, dstRect, mode, maskRgn)
- BitMap *srcBits;
- Rect *srcRect;
- Rect *dstRect;
- short mode;
- RgnHandle maskRgn;
- {
- CopyBits(
- srcBits,
- &thePort->portBits,
- srcRect, dstRect,
- mode,
- maskRgn
- );
- }
-
- /*
- * Called indirectly to read a chunk of picture data.
- */
- pascal void
- read_picture_data(data_ptr, byte_count)
- Ptr data_ptr;
- int byte_count;
- {
- OSErr status;
- long count;
-
- count = byte_count;
- status = FSRead(PICTfile, &count, data_ptr);
- if (status != noErr)
- DebugStr("\pReading picture");
- }
-
- /*
- * write_picture() writes the current picture to a
- * specified (open) file. It should be redone to
- * add error handling.
- */
- void
- write_picture(window, theFile)
- WindowPtr window;
- int theFile;
- {
- PicHandle picHandle;
- QDProcs procedures;
- int i;
- long temp;
- Picture header;
- GrafPtr tempPort;
- GrafPtr oldPort;
-
- GetPort(&oldPort);
- PICTfile = theFile;
- /*
- * Write the MacPaint header
- */
- temp = 0L;
- for (i = 0; i < 512; i += sizeof temp)
- write_picture_data((Ptr) &temp, (int) sizeof temp);
- header.picSize = 0;
- header.picFrame = DOC.pictSize;
- write_picture_data((Ptr) &header, (int) sizeof header);
- /*
- * Write the picture by creating a GrafPort with the
- * same dimensions as the original, then drawing the
- * cleaned up picture.
- */
- tempPort = CreateOSGrafPort(DOC.pictSize);
- if (tempPort == NIL) {
- DebugStr("\pNo space for temp port");
- return;
- }
- SetStdProcs(&procedures);
- tempPort->grafProcs = &procedures;
- procedures.putPicProc = (Ptr) write_picture_data;
- picHandle = OpenPicture(&tempPort->portRect);
- CopyOSGrafPort(DOC.pictPort, tempPort, NIL);
- ClosePicture();
- KillPicture(picHandle);
- DeleteOSGrafPort(tempPort);
- DOC.pictPort->grafProcs = NIL;
- SetPort(oldPort);
- }
-
- /*
- * Called indirectly to write a chunk of picture data.
- */
- pascal void
- write_picture_data(data_ptr, byte_count)
- Ptr data_ptr;
- int byte_count;
- {
- OSErr status;
- long count;
-
- count = byte_count;
- status = FSWrite(PICTfile, &count, data_ptr);
- if (status != noErr)
- DebugStr("\pWriting picture");
- }
-